/**
 * JAVACC DEMO 1.0
 * @copy right apache company All rights reserved. 
 * @Package com.apache.rpc.util  
 */
package com.apache.rpc.common;

import com.apache.api.vo.ResultEntity;
import com.apache.exception.ServiceException;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
import net.sf.ezmorph.Morpher;
import net.sf.ezmorph.MorpherRegistry;
import net.sf.ezmorph.bean.BeanMorpher;
import net.sf.ezmorph.bean.MorphDynaBean;
import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;
import net.sf.json.util.JSONUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * description:  工具类:javaBean xml json 相互转换
 * @author Hou Dayu 创建时间：2016-11-8
 * @Copyright(c)2014:
 */
public class JsonEntityParese {

	private Logger log = LoggerFactory.getLogger(JsonEntityParese.class);

	private static JsonEntityParese instance;

	private JsonEntityParese() {
		xstream = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("-_", "_")));
	}

	public static JsonEntityParese instance() {
		if (null == instance) {
			instance = new JsonEntityParese();
		}
		return (instance);
	}

	public String beanToJson(ResultEntity obj) {
		JSONObject json = JSONObject.fromObject(obj);
		return json.toString();
	}

	@SuppressWarnings("unchecked")
	private <T> T toBean(Class<T> cls, Object obj) {
		MorpherRegistry morpherRegistry = JSONUtils.getMorpherRegistry();
		Morpher dynaMorpher = new BeanMorpher(cls, morpherRegistry);
		morpherRegistry.registerMorpher(dynaMorpher);
		T ssb = (T) morpherRegistry.morph(cls, obj);
		return ssb;
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	private void toBeanForArrayList(List results, List objs, Class cls) {
		for (Object obj : objs) {
			Object result = toBean(cls, obj);
			results.add(result);
		}
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public <T> T jsonToBean(String jsonStr, Class<T> cls, Class attrCls) {
		T obj = null;
		Object java = JSONSerializer.toJava(JSONSerializer.toJSON(jsonStr));
		obj = (T) JsonEntityParese.instance().toBean(cls, java);
		try {
			if (cls.getSimpleName().equals("ResultEntity")) {
				ResultEntity ssb = (ResultEntity) obj;
				if (ssb.getEntity().getClass().isAssignableFrom(ArrayList.class)) {
					ArrayList lists = (ArrayList) ssb.getEntity();
					if (lists.get(0).getClass().isAssignableFrom(MorphDynaBean.class)) {
						List result = new ArrayList();
						JsonEntityParese.instance().toBeanForArrayList(result, lists, attrCls);
						ssb.setEntity(result);
					}
				} else if (ssb.getEntity().getClass().isAssignableFrom(MorphDynaBean.class)) {
					Object cols = JsonEntityParese.instance().toBean(attrCls, ssb.getEntity());
					ssb.setEntity(cols);
				}
				return (T) ssb;
			} else {
				JSONObject jsonObject = JSONObject.fromObject(jsonStr);
				obj = (T) JSONObject.toBean(jsonObject, cls);
			}
		} catch (Exception e) {
			log.error("异常",e);
			throw new ServiceException("json转成javaBean出错", e);
		}
		return obj;
	}

	private XStream xstream;

	private final String xmlHead = "<?xml version='1.0' encoding='UTF-8'?>\n";
	private final String xmlStart = "<xml-body>\n<Head></Head>\n<Body>\n";
	private final String xmlEnd = "\n</Body>\n</xml-body>";

	/**
	 * java 转换成xml
	 * @Title: toXml 
	 * @Description: TODO 
	 * @param obj 对象实例
	 * @return String xml字符串
	 */
	public String toXml(Object obj) {
		xstream.alias(obj.getClass().getSimpleName(), obj.getClass());
		return xmlHead + xmlStart + xstream.toXML(obj) + xmlEnd;
	}

	/**
	 * java 转换成xml
	 * @Title: toXml 
	 * @Description: TODO 
	 * @param obj 对象实例
	 * @return String xml字符串
	 */
	public String toXml(Object obj, Object objentity) {
		xstream.alias(obj.getClass().getSimpleName(), obj.getClass());
		if (null != objentity) {
			if (objentity.getClass().getSimpleName().equalsIgnoreCase("ArrayList")) {
				checkArrayList((List) objentity, xstream);
			} else {
				checkObject(objentity, xstream);
			}
		}
		return xmlHead + xmlStart + xstream.toXML(obj) + xmlEnd;
	}

	private void checkArrayList(List list, XStream xstream) {
		Object obj = list.get(0);
		Class clazz = obj.getClass();
		xstream.alias(clazz.getSimpleName(), clazz);
	}

	private void checkObject(Object obj, XStream xstream) {
		Class clazz = obj.getClass();
		if (clazz.getName().indexOf("com.apache") != -1) {
			xstream.alias(clazz.getSimpleName(), clazz);
		}
	}

	/**
	 *  将传入xml文本转换成Java对象
	 * @Title: toBean 
	 * @Description: TODO 
	 * @param xmlStr
	 * @param cls  xml对应的class类
	 * @return T   xml对应的class类的实例对象
	 * 
	 * 调用的方法实例：PersonBean person=XmlUtil.toBean(xmlStr, PersonBean.class);
	 */
	public <T> T toBean(String xmlStr, Class<T> cls) {
		xmlStr = xmlStr.trim();
		xmlStr = xmlStr.replaceAll(xmlStart, "");
		xmlStr = xmlStr.replaceAll(xmlEnd, "");
		xstream.alias(cls.getSimpleName(), cls);
		//		if (!Validator.isEmpty(entityCls)) {
		//			xstream.alias(entityCls.getSimpleName(), entityCls.getClass());
		//		}
		T obj = (T) xstream.fromXML(xmlStr);
		return obj;
	}

	public String javaBeanToJson(Object obj) {
		JSONObject json = JSONObject.fromObject(obj);
		return json.toString();
	}

	public <T> T jsonToJavaBean(String json, Class<T> cls, Class entityCls) {
		JSONObject jsonObject = JSONObject.fromObject(json);
		Map<String, Class> clazzMap = new HashMap<String, Class>();
		clazzMap.put("entity", entityCls);
		return (T) JSONObject.toBean(jsonObject, cls, clazzMap);
	}

}
